/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "callinstructionlogic.h"
#include "GeneralDefine.h"
#include "programengine.h"
#include "messagelog.h"

CallInstructionLogic::CallInstructionLogic(int robotIdIn, ProgramSet* programSetIn, RobotIo* ioControllerIn
                                           , ProgramEngine* programEngineIn, PointData *pointDataIn
                                           , QVector <PointPro> *getPointProListIn
                                           , QVector <QVector <PointPro> > *allPointProListIn,
                                           McControllerThread *programMcControllerIn)
{
    programSet=programSetIn;
    robotId=robotIdIn;
    ioController=ioControllerIn;
    programEngine=programEngineIn;
    pointData=pointDataIn;
    getPointProList=getPointProListIn;

    allPointProList=allPointProListIn;
    programMcController=programMcControllerIn;

}

E_PROGRAM_LOOP_RESULT CallInstructionLogic::startCall(int fatherProgramIndex,QString tocallProgramName)
{
    qDebug() <<"***CallInstructionLogic::startCall ****"<<tocallProgramName<<"==fatherProgramIndex=="
             <<fatherProgramIndex<<"\n\n\n\n";
    E_PROGRAM_LOOP_RESULT endFlag = E_PROGRAM_LOOP_RESULT_NORMAL;

    int childProgramIndex;
    if(false==isProgramFileLoaded(tocallProgramName,childProgramIndex))
    {
        qDebug() <<"***loadProgramFile ****";
        bool isOk;
        isOk= loadProgramFile(fatherProgramIndex,tocallProgramName);
        if(false==isOk)
        {
            programEngine->cmdError(fatherProgramIndex);
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

    }
    else
    {
        qDebug() <<"***no loadProgramFile ****";
//        changePointPro(childProgramIndex);
        programEngine->loadPointAndPalInfo(childProgramIndex);
    }

    for(int i = 0; i < programSet->size();i++)
    {
        if(tocallProgramName == (*programSet)[i].thisProgramName)
        {
            qDebug() <<"***call****"<<tocallProgramName<<"==i==="<<i<<"\n\n\n\n";
            (*programSet)[i].runningLineInt=0;
            (*programSet)[i].runState = true;
            (*programSet)[i].fatherProgramName =
                    (*programSet)[fatherProgramIndex].thisProgramName;

            break;
        }
        else
        {
//            qDebug() <<"***call****"<<callProgramName<<"==i=***false*****=="<<i<<"\n\n";

            (*programSet)[i].runState = false;
        }

    }

    programEngine->setPcFlagValue(0.0);
    programEngine->setRunningLineFloat(0.02);
    programEngine->setCurrentProgramName(tocallProgramName);

    if(programEngine->getRunModel()<ENUM_CONTROL_AUTO)
    {
        programEngine->set_mamual_run_flag(false) ;
    }

    qDebug() <<"***call out! ****";

    return endFlag;
}

//bool CallInstructionLogic::changePointPro(int programIndex)
//{
//    if(NULL != pointData)
//    {
//        //将解析出来的普通点的数据发送到ｐｏｉｎｔＤａｔａ
//        if(0 < getPointProList->size())
//        {
//            pointData->savePoint2List((*allPointProList)[programIndex]);
//            qDebug()<< "call ,pointData change点位数据! "<<getPointProList->size();
//        }
//        //将解析出来的码垛点的数据发送到ｐｏｉｎｔＤａｔａ
//        if(0 < palletStackInfo->size())
//        {
//            pointData->savePalletPoint2List((*allStackInfoList)[programIndex]);

//        }
//    }
//    return true;
//}

bool CallInstructionLogic::loadProgramFile(int fatherProgramIndex, QString programFileIn)
{
    if(D_MAX_CALL_PROGRAM_NUMBER<(*programSet).size())
    {
        addMsg(ENUM_MSG_ERROR,"ProgramEngine","ProgramEngine",3011,robotId,D_MAX_CALL_PROGRAM_NUMBER);
        qDebug()<<"call file exceed limit"<<(*programSet).size();
        return false;
    }

    //判断文件是否存在
    QString tmpFilePath=D_TCRCONTROLLER_DATA_PATH;
    QString callFile = tmpFilePath+ROBOT_COMMON_NAME + QString::number(robotId)
            + ROBOT_PROGRAM_FLODER + programFileIn;//可能call提取正则表达式有问题。

    int returnkey ;

    returnkey = programEngine->readOneProgramFile(callFile);// 解释程式  HUALEI need todo ,not read program every time
    if( returnkey )
    {
        if( returnkey ==-2 )
        {
            addMsg(ENUM_MSG_ERROR,"ProgramEngine","ProgramEngine",3009,robotId,0,0,0,0,programFileIn);
            qDebug()<<"文件不存在 readProgram（？）"<<callFile;
            return false;
        }
    }
    if( callFile.isEmpty() )
    {
        //消息预留
        qDebug()<<"运行程式名为空 readProgram（？）"<<callFile;
        addMsg(ENUM_MSG_ERROR,"ProgramEngine","ProgramEngine",3008,robotId);
        return false;
    }

    QFile file(callFile);
    if( !file.exists() )
    {
        addMsg(ENUM_MSG_ERROR,"ProgramEngine","ProgramEngine",3009,robotId,0,0,0,0,programFileIn);
        qDebug()<<"文件不存在 readProgram（？）"<<callFile;
        return false;
    }

//    programEngine->setProgramCountNum(programEngine->getProgramCountNum()+1);



//    qDebug() << "===pCount=="<<programEngine->getRunningLineFloat() << "\n\n";

    QVector<QString> listStrOut;
    programEngine->getCmdStrList(listStrOut);
    int returnKey = programSet->transferTextInstructionToStructData(
                listStrOut,(*programSet).size()
                ,programEngine->getCurrentProgramName(),programEngine->getEngineStatue(),robotId);
    if( returnKey < 0 )
    {
        programSet->clear();
        addMsg( ENUM_MSG_ERROR,  "ProgramEngine", "ProgramEngine",  3010,  robotId ,   returnKey );
        return false;
    }
    else if( returnKey > 0 )
    {

        addMsg( ENUM_MSG_ERROR,  "ProgramEngine", "ProgramEngine",  3010,  robotId ,   returnKey );
        return false;
    }
    else
    {

        (*programSet)[(*programSet).size()-1].thisProgramName = programFileIn;
        (*programSet)[(*programSet).size()-1].fatherProgramName=
                (*programSet)[fatherProgramIndex].thisProgramName;
        programEngine->pretreatMotion();
    }

    return true;
}

bool CallInstructionLogic::isProgramFileLoaded(QString programFileIn, int &programIndexOut)
{
    for(int i=0;i<programSet->size();i++)
    {
        if((*programSet)[i].thisProgramName==programFileIn)
        {
            programIndexOut=i;
            return true;
        }
    }

    return false;
}


void CallInstructionLogic::addMsg(int messageLevel, string componentName, string messageType,
                           int messageCode, int robotId,
                           int parameter1, int parameter2, int parameter3, int parameter4,
                                  QString message)
{
    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
   // tmpMsg.time = t1.tv_sec;


    QString infomationStr;

    switch(messageCode)
    {
    case 3011:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",调用文件层级超过允许数量") + QString::number(parameter1);
        break;
    }

    case 3010:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",读取文件指令错误,行号") + QString::number(parameter1);
        break;
    }

    case 3009:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId) + QObject::tr(",") ;
        infomationStr = infomationStr +"程序文件("+ message + QObject::tr(")不存在!");
        break;
    }


    case 3008:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",程式名为空! ");
         break;

    }



    default:
    {

    }
    }


    tmpMsg.MessageInformation = infomationStr.toStdString();

    // qDebug()<<"53444444444444444444444"<< tmpMsg.messageCode;
    MessageLog::getInstance()->addMessage(tmpMsg);
}
